<template>
  <div class="w-progress" :class="classes" :style="styles">
    <div
      class="w-progress__progress"
      v-if="!circle"
      :class="{ full: progressValue === 100 }"
      :style="`width: ${progressValue}%`"
    ></div>
    <template v-else
      ><svg
        :viewBox="
          `${circleCenter / 2} ${circleCenter /
            2} ${circleCenter} ${circleCenter}`
        "
      >
        <circle
          class="bg"
          v-if="bgColor || this.progressValue > -1"
          :class="bgColor"
          :cx="circleCenter"
          :cy="circleCenter"
          :r="circleRadius"
          fill="transparent"
          :stroke-dasharray="circleCircumference"
          :stroke-width="stroke"
        ></circle>
      </svg>
      <svg
        class="w-progress__progress"
        :viewBox="
          `${circleCenter / 2} ${circleCenter /
            2} ${circleCenter} ${circleCenter}`
        "
        :style="
          `stroke-dashoffset: ${(1 - progressValue / 100) *
            circleCircumference}`
        "
      >
        <circle
          :cx="circleCenter"
          :cy="circleCenter"
          :r="circleRadius"
          fill="transparent"
          :stroke-width="stroke"
          :stroke-linecap="roundCap && 'round'"
          :stroke-dasharray="circleCircumference"
        ></circle>
      </svg>
    </template>
    <div
      class="w-progress__label"
      v-if="label || $slots.default"
      :class="labelColor || false"
    >
      <slot>{{ Math.round(progressValue) }}{{ circle ? "" : "%" }}</slot>
    </div>
  </div>
</template>

<script>
/**
 * This component (circular) is hacked to work on Edge as it does not support transform on svg elements.
 * https://caniuse.com/#feat=mdn-css_properties_transform-origin_support_in_svg
 * It is meant to be 2 circles in 1 svg, with animation on the circle, now instead, there are 2 svgs,
 * and the animation is on the second svg itself.
 */

// For circular progress.
// const circleSize = 40;
// const circleRadius = circleSize / 2;
// const circleCircumference = Math.round(circleSize * 3.14 * 100) / 100;
import { ref, computed } from "vue";
export default {
  name: "w-progress",

  props: {
    modelValue: { type: [Number, String, Boolean], default: -1 },
    label: { type: Boolean },
    roundCap: { type: Boolean },
    color: { type: String, default: "primary" },
    bgColor: { type: String },
    labelColor: { type: String },
    size: { type: [Number, String] },

    // Circular progress thickness.
    circle: { type: Boolean },
    stroke: { type: [Number, String], default: 4 },

    // For linear progress.
    shadow: { type: Boolean },
    tile: { type: Boolean },
    round: { type: Boolean },
    outline: { type: Boolean },
    stripes: { type: Boolean },
    absolute: { type: Boolean },
    fixed: { type: Boolean },
    top: { type: Boolean },
    bottom: { type: Boolean },
    zIndex: { type: [Number, String, Boolean] }
  },

  emits: [],
  setup(props, ctx) {
    const circleSize = ref(40);
    const circleRadius = circleSize.value / 2;
    const circleCircumference = Math.round(circleSize.value * 3.14 * 100) / 100;

    const progressValue = computed(() => {
      return parseFloat(props.modelValue);
    });

    const circleCenter = computed(() => {
      return circleSize.value + props.stroke;
    });

    const forcedSize = computed(() => {
      return (
        props.size && (!isNaN(props.size) ? `${props.size}px` : props.size)
      );
    });

    // If linear, with position fixed or absolute.
    const position = computed(() => {
      return (props.top && "top") || (props.bottom && "bottom") || "top";
    });

    const classes = computed(() => {
      return {
        [`w-progress--${props.circle ? "circular" : "linear"}`]: true,
        [props.color]: props.color,
        [`${props.bgColor}--bg`]: props.bgColor && !props.circle,
        [`w-progress--${position.value}`]:
          !props.circle && (props.absolute || props.fixed),
        "w-progress--default-bg": !props.bgColor,
        "w-progress--indeterminate": props.modelValue === -1,
        "w-progress--outline": !props.circle && props.outline,
        "w-progress--tile": !props.circle && props.tile,
        "w-progress--stripes": !props.circle && props.stripes,
        "w-progress--round": !props.circle && props.round,
        "w-progress--shadow": props.shadow,
        "w-progress--absolute": !props.circle && props.absolute,
        "w-progress--fixed": !props.circle && !props.absolute && props.fixed,
        [`w-progress--${props.roundCap ? "round" : "flat"}-cap`]: true
      };
    });

    const styles = computed(() => {
      return {
        [props.circle ? "width" : "height"]: forcedSize.value || null
      };
    });

    return {
      circleSize,
      circleRadius,
      circleCircumference,
      progressValue,
      // computed
      circleCenter,
      forcedSize,
      position,
      classes,
      styles
    };
  }
};
</script>